package io.gitee.kotle.player.download.impl

import io.gitee.kotle.player.download.IPlayerDownload
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch

/**
 *
 * 描述：下载器，处理通用逻辑
 *
 * @author Jiale.Wei
 *
 * 创建时间：2023/4/26 14:44
 *
 */
abstract class BasePlayerDownload<Media> : IPlayerDownload<Media> {

    /**
     * 定时器
     */
    private var loopJob: Job? = null


    /**
     * 监听器集合
     */
    val listeners = mutableListOf<Pair<String?, IPlayerDownload.IListener<Media>>>()

    private val _scope: CoroutineScope = MainScope()
    override val scope: CoroutineScope
        get() = _scope

    override fun addListener(listener: Pair<String?, IPlayerDownload.IListener<Media>>?) {
        listener ?: return
        if (!listeners.contains(listener)) {
            listeners.add(listener)
        }
    }

    override fun removeListener(listener: Pair<String?, IPlayerDownload.IListener<Media>>?) {
        listener ?: return
        if (listeners.contains(listener)) {
            listeners.remove(listener)
        }
    }

    /**
     * 开始循环
     */
    fun startLoop() {
        val job = loopJob
        if (job?.isActive == true) {
            return
        }
        loopJob = scope.launch {
            while (isActive) {
                val startMillis = System.currentTimeMillis()
                onLoopRun(this)
                val customDuration = System.currentTimeMillis() - startMillis
                val leftDuration = getLoopJobInterval() - customDuration
                if (leftDuration > 0) {
                    delay(leftDuration)
                }
            }
        }
    }

    /**
     * 循环任务
     */
    open suspend fun onLoopRun(scope: CoroutineScope) {

    }

    /**
     * 取消循环
     */
    fun cancelLoop() {
        val job = loopJob
        if (job?.isActive == true) {
            job.cancel()
        }
        loopJob = null
    }

    override fun release() {
        cancelLoop()
        listeners.clear()
        scope.cancel()
    }

    /**
     * 循环间隔
     */
    open fun getLoopJobInterval(): Long = 1000
}